package com.ease.integration.jms.support;

import java.util.Enumeration;

import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.TextMessage;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class JmsDebugger {
	private static final transient Log log = LogFactory.getLog(JmsDebugger.class);

	@SuppressWarnings("unchecked")
	public static String getMessageDebugInfo(final Message message) {
		if (null == message) {
			return null;
		}
		try {
			StringBuilder sb = new StringBuilder();
			sb.append("{header: {JMSMessageID=" + message.getJMSMessageID());

			sb.append(", JMSCorrelationID=").append(message.getJMSCorrelationID());
			sb.append(", JMSDestination=").append(message.getJMSDestination());
			sb.append(", JMSRedelivered=").append(message.getJMSRedelivered());
			sb.append(", JMSTimestamp=").append(message.getJMSTimestamp());

			sb.append("},{properties: {");

			Enumeration<String> propertyNames = message.getPropertyNames();

			while (propertyNames.hasMoreElements()) {
				String propName = (String) propertyNames.nextElement();
				sb.append(propName).append("=").append(message.getStringProperty(propName)).append(", ");
			}

			if (message instanceof TextMessage) {
				sb.append("}, body: ").append(((TextMessage) message).getText());
			}

			if (message instanceof MapMessage) {
				sb.append("}; {Map values: ");
				MapMessage mapMsg = (MapMessage) message;
				Enumeration<String> mapNames = mapMsg.getMapNames();
				while (mapNames.hasMoreElements()) {
					String propName = (String) mapNames.nextElement();
					sb.append(propName).append("=").append(mapMsg.getString(propName)).append(", ");
				}
			}
			sb.append("}.");
			return sb.toString();
		} catch (JMSException e) {
			throw new RuntimeException("Catch unexpected JMSException", e);
		}
	}

	@Before("execution(* *..*MessageListener+.onMessage(javax.jms.Message)) && args(message)")
	public void debugJmsMessage(final Message message) {
		log.info("Received Message: " + getMessageDebugInfo(message));
	}

	@AfterThrowing(pointcut = "execution(* *..*MessageListener+.onMessage(javax.jms.Message)) && args(message)", throwing = "e")
	public void debugJmsMessageOnException(final Message message, final Throwable e) {
		log.info("Error Processing Message: " + getMessageDebugInfo(message));
	}
}
